ShiroAdminToken验证类:负责装填验证信息 并传给Shiro进行处理验证
package com.xiwi.vip.ziti.common.shiro; import org.apache.shiro.authc.UsernamePasswordToken; public class ShiroAdminToken extends UsernamePasswordToken { private String tokenType; public ShiroAdminToken(final String username, final String password, String tokenType) { super(username, password); this.tokenType = tokenType; } public String getTokenType() { return tokenType; } public void setTokenType(String tokenType) { this.tokenType = tokenType; } }
|
用户使用账号密码进行登录。(前端请求服务器,服务器收到请求,通过 ShiroAdminToken验证类 填写验证信息交给Shiro进行验证登录)
Subject subject = SecurityUtils.getSubject(); ShiroAdminToken shiroAdminToken = new ShiroAdminToken( paramsMap.get("account").toString(), paramsMap.get("password").toString(), "AdminUser" ); try { subject.login(shiroAdminToken); } catch (UnknownAccountException e) { return ResultJson.response(-1, e.getMessage()); } catch (AuthenticationException e) { return ResultJson.response(-1, e.getMessage()); } catch (AuthorizationException e) { return ResultJson.response(-1, e.getMessage()); } catch (Exception e) { return ResultJson.response(-1, e.getMessage()); }
AdminUser adminUser = (AdminUser) SecurityUtils.getSubject().getPrincipal();
String token = IdUtil.simpleUUID(); timedCache.put(token, adminUser, 86400); redisUtil.set(token, adminUser, 86400);
this.adminId = adminUser.getId().longValue(); this.adminUser = adminUser;
Map<String, Object> result = new LinkedHashMap<String, Object>() {{ put("user_info", adminUser); put("token", token); }};
|
AdminUserRealm类:用户名密码验证类
package com.xiwi.vip.ziti.common.shiro.realm; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; import com.xiwi.vip.ziti.common.core.PasswordUtil; import com.xiwi.vip.ziti.common.core.ResultJson; import com.xiwi.vip.ziti.entity.AdminUser; import com.xiwi.vip.ziti.service.AdminUserService; import org.apache.shiro.authc.*; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import javax.annotation.Resource; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; public class AdminUserRealm extends AuthorizingRealm { @Resource private AdminUserService adminUserService; @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { return null; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { if (StrUtil.isBlankIfStr(authenticationToken.getPrincipal())) { throw new UnknownAccountException("用户不存在"); } String account = authenticationToken.getPrincipal().toString(); String password = new String((char[])authenticationToken.getCredentials()); List<AdminUser> adminUserList = adminUserService.lambdaQuery() .eq(AdminUser::getAccount, account) .eq(AdminUser::getDelFlag, 0) .list(); if (adminUserList.size() != 1) { throw new UnknownAccountException("用户不存在"); } AdminUser adminUser = adminUserList.get(0); if (!adminUser.getPassword().equals(PasswordUtil.encrypt(password))) { throw new AuthenticationException("密码错误"); }
return new SimpleAuthenticationInfo(adminUser, password, getName()); } }
|
AdminTokenRealm类:协议头token登录验证类
package com.xiwi.vip.ziti.common.shiro.realm; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.xiwi.vip.ziti.common.core.PasswordUtil; import com.xiwi.vip.ziti.common.core.RedisUtil; import com.xiwi.vip.ziti.common.core.ResultJson; import com.xiwi.vip.ziti.common.exception.ApplicationRunTimeException; import com.xiwi.vip.ziti.entity.AdminUser; import com.xiwi.vip.ziti.service.AdminUserService; import org.apache.shiro.authc.*; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import javax.annotation.Resource; import java.util.List; public class AdminTokenRealm extends AuthorizingRealm { @Resource private RedisUtil redisUtil; @Resource private AdminUserService adminUserService; @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { return null; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { if (StrUtil.isBlankIfStr(authenticationToken.getPrincipal())) { throw new ApplicationRunTimeException(ResultJson.response(-1000, "未登录")); } String token = authenticationToken.getPrincipal().toString(); System.out.println( "AdminTokenRealm... token: " + token ); if (StrUtil.isBlankIfStr(token)) {
throw new UnknownAccountException(); } if (ObjectUtil.hasNull(redisUtil.get(token))) {
throw new UnknownAccountException(); } AdminUser adminUser = redisUtil.get(token, AdminUser.class); adminUser = adminUserService.lambdaQuery() .eq(AdminUser::getId, adminUser.getId()) .one(); System.out.println( "AdminTokenRealm... login:" + adminUser.toString() ); return new SimpleAuthenticationInfo(adminUser, token, getName()); } }
|
多Realm的处理类
package com.xiwi.vip.ziti.common.shiro; import com.xiwi.vip.ziti.common.shiro.realm.AdminTokenRealm; import com.xiwi.vip.ziti.common.shiro.realm.AdminUserRealm; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.pam.ModularRealmAuthenticator; import org.apache.shiro.authz.Authorizer; import org.apache.shiro.authz.ModularRealmAuthorizer; import org.apache.shiro.realm.Realm; import org.apache.shiro.subject.PrincipalCollection; import java.util.ArrayList; import java.util.Collection; import java.util.List; public class UserModularRealmAuthorizer extends ModularRealmAuthenticator { @Override protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException { assertRealmsConfigured(); ShiroAdminToken userToken = (ShiroAdminToken) authenticationToken; String loginType = userToken.getTokenType(); Collection<Realm> realms = getRealms(); List<Realm> typeRealms = new ArrayList<>(); for (Realm realm : realms) { if (realm.getName().contains(loginType)) { typeRealms.add(realm); } } if (typeRealms.size() == 1){ return doSingleRealmAuthentication(typeRealms.get(0), userToken); } else { return doMultiRealmAuthentication(typeRealms, userToken); } } }
|
ShiroAuthFilter拦截器:因为我这里是有带协议头的登录验证方式 所以要加这个 其它方式看情况定
package com.xiwi.vip.ziti.common.shiro; import cn.hutool.cache.impl.TimedCache; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import com.xiwi.vip.ziti.common.core.RedisUtil; import com.xiwi.vip.ziti.common.core.ResultJson; import com.xiwi.vip.ziti.service.AdminUserService; import org.apache.shiro.web.filter.authz.AuthorizationFilter; import javax.annotation.Resource; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import java.io.IOException; public class ShiroAuthFilter extends AuthorizationFilter { @Resource private TimedCache<String, Object> timedCache; @Resource private RedisUtil redisUtil; @Resource private AdminUserService adminUserService; @Override protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception { HttpServletRequest request1 = (HttpServletRequest) servletRequest; String token = request1.getHeader("admin-auth"); System.out.println( "isAccessAllowed... token: " + token ); if (StrUtil.isBlankIfStr(token)) { return false; } ShiroAdminToken shiroAdminToken = new ShiroAdminToken(token, token, "AdminToken"); try { getSubject(servletRequest, servletResponse).login(shiroAdminToken); }catch (Exception e) { return false; } return true; } @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception { System.out.println("ShiroAuthFilter onAccessDenied..."); response.setContentType("application/json;charset=utf-8"); response.getWriter().write(JSONUtil.parseObj(ResultJson.response(-1000, "未登录")).toString()); response.getWriter().flush(); response.getWriter().close(); return false; } @Override protected void redirectToLogin(ServletRequest request, ServletResponse response) throws IOException { response.getWriter().write(JSONUtil.parseObj(ResultJson.response(-1000, "未登录")).toString()); response.getWriter().flush(); response.getWriter().close(); } protected boolean onAccessDenied2(ServletRequest request, ServletResponse response) { return true; } }
|
package com.xiwi.vip.ziti.common.config; import com.xiwi.vip.ziti.common.shiro.ShiroAuthFilter; import com.xiwi.vip.ziti.common.shiro.UserModularRealmAuthorizer; import com.xiwi.vip.ziti.common.shiro.realm.AdminTokenRealm; import com.xiwi.vip.ziti.common.shiro.realm.AdminUserRealm; import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy; import org.apache.shiro.authc.pam.ModularRealmAuthenticator; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.realm.Realm; import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.servlet.Filter; import java.util.*; @Configuration public class ShiroConfig { @Bean public AdminUserRealm adminUserRealm() { return new AdminUserRealm(); } @Bean public AdminTokenRealm adminTokenRealm() { return new AdminTokenRealm(); } @Bean public ShiroAuthFilter shiroAuthFilter() { return new ShiroAuthFilter(); } @Bean public ModularRealmAuthenticator modularRealmAuthenticator(){ UserModularRealmAuthorizer userModularRealmAuthorizer = new UserModularRealmAuthorizer(); userModularRealmAuthorizer.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy()); return userModularRealmAuthorizer; } @Bean(name = "securityManager") public SecurityManager securityManager() { DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
defaultWebSecurityManager.setAuthenticator(modularRealmAuthenticator()); List<Realm> realmList = new ArrayList<>(); realmList.add(adminUserRealm()); realmList.add(adminTokenRealm()); defaultWebSecurityManager.setRealms(realmList); return defaultWebSecurityManager; } @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager")SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); Map<String, Filter> filters=new LinkedHashMap<>(); filters.put("authc", new ShiroAuthFilter()); shiroFilterFactoryBean.setFilters(filters); Map<String, String> map = new LinkedHashMap<>(); map.put("/admin/oauth/**", "anon"); map.put("/admin/**", "authc"); map.put("/**", "authc"); shiroFilterFactoryBean.setFilterChainDefinitionMap(map); return shiroFilterFactoryBean; }
@Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){ AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } }
|